package com.culturalyard.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.culturalyard.constant.MessageConstant;
import com.culturalyard.exception.NetworkException;
import com.culturalyard.exception.RequestOnlineStateException;
import com.culturalyard.exception.RequestTokenException;
import com.culturalyard.exception.RequestVideoUrlException;
import com.culturalyard.properties.YingShiPorperties;
import com.culturalyard.service.OpenApiService;
import com.culturalyard.utils.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class OpenApiServiceImpl implements OpenApiService {
    @Autowired
    private YingShiPorperties yingShiPorperties;

    private static final String APP_KEY = "appKey";
    private static final String APP_SECRET = "appSecret";
    private static final String YINGSHI_TOKEN = "ys_token";
    private static final String SUCCESS_CODE = "200";

    private static final String ACCESS_TOKEN = "accessToken";
    private static final String DEVICE_SERIAL = "deviceSerial";
    // 获取accessToken
    public String getAccessToken(String appKey,String secret){
        String accessToken = "";

        Map<String,String> paramMap = new HashMap<>();
        paramMap.put(APP_KEY,appKey);
        paramMap.put(APP_SECRET,secret);

        String json;
        try{
            json = HttpUtil.doPostByForm(yingShiPorperties.getTokenUrl(), paramMap);
        } catch (IOException e) {
            // 网络抖动，向萤石开放平台请求发生错误
            throw new NetworkException(MessageConstant.NETWORK_ERROR);
        }

        JSONObject jsonObject = JSON.parseObject(json);
        JSONObject data = jsonObject.getJSONObject("data");

        String code = jsonObject.getString("code");
        log.info("萤石开放平台返回状态码：{}，响应信息：{}",code,jsonObject.getString("msg"));
        if (code.equals(SUCCESS_CODE)){
            accessToken = data.getString("accessToken");
            Long expireTime = data.getLong("expireTime");
            log.info("已重新获取accessToken，过期时间：{}",new Date(expireTime));
        }else{
            throw new RequestTokenException(MessageConstant.REQUEST_TOKEN_ERROR);
        }
        return accessToken;
    }

    /**
     * 获取设备的在线情况（0：离线，1：在线）
     * @param sequenceNumber
     * @param accessToken
     * @return
     */
    @Override
    public Integer getOnlineState(String sequenceNumber, String accessToken) {
        Map<String,String> paramMap = new HashMap<>();
        paramMap.put(ACCESS_TOKEN,accessToken);
        paramMap.put(DEVICE_SERIAL,sequenceNumber);

        String json;
        try{
            json = HttpUtil.doPostByForm(yingShiPorperties.getOnlineStateUrl(), paramMap);
        } catch (IOException e) {
            // 网络抖动，向萤石开放平台请求发生错误
            throw new NetworkException(MessageConstant.NETWORK_ERROR);
        }

        JSONObject jsonObject = JSON.parseObject(json);
        JSONObject data = jsonObject.getJSONObject("data");

        String code = jsonObject.getString("code");
        log.info("萤石开放平台返回状态码：{}，响应信息：{}",code,jsonObject.getString("msg"));
        if (code.equals(SUCCESS_CODE)){
            Integer onlineState = data.getInteger("status");
            // accessToken设置到redis,并设置过期时间
            log.info("成功获取序列号为：{}的设备状态{} (0:离线，1:在线)",sequenceNumber,onlineState);
            return onlineState;
        }else{
            throw new RequestOnlineStateException(MessageConstant.REQUEST_ONLINE_STATE_ERROR);
        }
    }

    /**
     * 获取摄像头视频地址
     * @param sequenceNumber
     * @param accessToken
     * @return
     */
    @Override
    public String getVideoUrl(String sequenceNumber, String accessToken) {
        Map<String,String> paramMap = new HashMap<>();
        paramMap.put(ACCESS_TOKEN,accessToken);
        paramMap.put(DEVICE_SERIAL,sequenceNumber);

        String json;
        try{
            json = HttpUtil.doPostByForm(yingShiPorperties.getVideoUrl(), paramMap);
        } catch (IOException e) {
            // 网络抖动，向萤石开放平台请求发生错误
            throw new NetworkException(MessageConstant.NETWORK_ERROR);
        }

        JSONObject jsonObject = JSON.parseObject(json);
        JSONObject data = jsonObject.getJSONObject("data");

        String code = jsonObject.getString("code");
        log.info("萤石开放平台返回状态码：{}，响应信息：{}",code,jsonObject.getString("msg"));
        if (code.equals(SUCCESS_CODE)){
            String videoUrl = data.getString("url");
            // accessToken设置到redis,并设置过期时间
            log.info("成功获取序列号为：{}的直播地址：{}",sequenceNumber,videoUrl);
            return videoUrl;
        }else{
            throw new RequestVideoUrlException(MessageConstant.REQUEST_VIDEO_URL_ERROR);
        }
    }
}
